#define WIN32_LEAN_AND_MEAN
#define BUILD_COMFUNCT_DLL

#define _WIN32_WINNT 0x0500 /* For the VK_* values in the hook procedure */

#include <windows.h>
#include <wininet.h>
#include <commctrl.h>
#include <shlwapi.h>
#include "comfunct.h"
#include "../resource.h"

typedef const TCHAR* (__cdecl*TRANSLATEPROC)(unsigned int);
TRANSLATEPROC tpGetText = NULL;
HINSTANCE hLanguageDll = NULL;

BOOL CALLBACK DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpNull)
{
	switch(dwReason)
	{
		case DLL_PROCESS_DETACH:
		{
			FreeLibrary(hLanguageDll);
		}
		break;
	}
}

EXPORT_COMFUNCT void __cdecl SetStatusA(HWND hwnd, UINT iStatusIdent, int iBarPart, LPCSTR message)
{
    SendDlgItemMessageA(hwnd, iStatusIdent, SB_SETTEXTA, iBarPart, (LPARAM)message);
    return;
}

EXPORT_COMFUNCT HINTERNET __cdecl ConnectHandleA(LPCSTR szUserAgent)
{
    HINTERNET hInitConnect = NULL;
    hInitConnect = InternetOpenA(szUserAgent, INTERNET_OPEN_TYPE_PRECONFIG,
                                        NULL, NULL, 0);
    return hInitConnect;
}

EXPORT_COMFUNCT HINTERNET __cdecl ServerConnectA(HINTERNET hInitHandle, LPCSTR szHostName)
{
    HINTERNET hConnection = NULL;
    hConnection = InternetConnectA(hInitHandle, szHostName, INTERNET_DEFAULT_HTTP_PORT,
                                  "", "", INTERNET_SERVICE_HTTP, 0, 0);
    return hConnection;
}

EXPORT_COMFUNCT void __cdecl SetStatusW(HWND hwnd, UINT iStatusIdent, int iBarPart, LPCWSTR message)
{
    SendDlgItemMessageW(hwnd, iStatusIdent, SB_SETTEXTW, iBarPart, (LPARAM)message);
    return;
}

EXPORT_COMFUNCT HINTERNET __cdecl ConnectHandleW(LPCWSTR szUserAgent)
{
    HINTERNET hInitConnect = NULL;
    hInitConnect = InternetOpenW(szUserAgent, INTERNET_OPEN_TYPE_PRECONFIG,
                                        NULL, NULL, 0);
    return hInitConnect;
}

EXPORT_COMFUNCT HINTERNET __cdecl ServerConnectW(HINTERNET hInitHandle, LPCWSTR szHostName)
{
    HINTERNET hConnection = NULL;
    hConnection = InternetConnectW(hInitHandle, szHostName, INTERNET_DEFAULT_HTTP_PORT,
                                  L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
    return hConnection;
}

EXPORT_COMFUNCT char* __cdecl ASCIIConversion(LPCWSTR wszWideString)
{
    int iLen = 0;
	char* szNarrowString = NULL;
	if(wszWideString == NULL)
	{
		return NULL;
	}
	iLen = lstrlenW(wszWideString);
    szNarrowString = HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, (iLen + sizeof(char)));
    WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wszWideString, iLen + sizeof(WCHAR), szNarrowString, iLen + sizeof(char), NULL, NULL);
    return szNarrowString;
}

EXPORT_COMFUNCT WCHAR* __cdecl UnicodeConversion(LPCSTR szNarrowString)
{
    int iLen = 0;
	WCHAR* wszWideString = NULL;
	if(szNarrowString == NULL)
	{
		return NULL;
	}
	iLen = lstrlenA(szNarrowString);
    wszWideString = HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, ((iLen + 1) * sizeof(WCHAR)));
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szNarrowString, -1, wszWideString, iLen + sizeof(WCHAR));
    return wszWideString;
}

BOOL CALLBACK RealChangeTextFont(HWND hwnd, LPARAM hfFont)
{
	SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfFont, MAKELPARAM(TRUE, 0));
	return TRUE;
}

EXPORT_COMFUNCT void __cdecl ChangeTextFont(HWND hwnd, HFONT hfFont)
{
	EnumChildWindows(hwnd, RealChangeTextFont, (LPARAM)hfFont);
	return;
}

EXPORT_COMFUNCT void __cdecl FreePointer(void* lpMemToFree)
{
	HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, lpMemToFree);
	return;
}

EXPORT_COMFUNCT const char* __cdecl GetLocalTextA(unsigned int iIndex)
{
	return (const char*)tpGetText(iIndex);
}

EXPORT_COMFUNCT const WCHAR* __cdecl GetLocalTextW(unsigned int iIndex)
{
	return (const WCHAR*)tpGetText(iIndex);
}

EXPORT_COMFUNCT void __cdecl SetupLanguage(void)
{
	WIN32_FIND_DATAA wfd;
	HANDLE hFile = NULL;
	char szFile[MAX_PATH], szSearchParam[MAX_PATH];
	szFile[0] = 0;
	szSearchParam[0] = 0;

	GetModuleFileNameA(GetModuleHandleA(NULL), szSearchParam, MAX_PATH);
	PathRemoveFileSpecA(szSearchParam);
	lstrcatA(szSearchParam, "\\");
	lstrcpyA(szFile, szSearchParam);
	lstrcatA(szSearchParam, "lang_*.*");
	hFile = FindFirstFileA(szSearchParam, &wfd);
	do
	{
		if(StrStrIA(wfd.cFileName, ".dll") != NULL)
		{
			lstrcatA(szFile, wfd.cFileName);
			break;
		}
	}
	while(FindNextFileA(hFile, &wfd) != 0);
	FindClose(hFile);
	hLanguageDll = LoadLibraryA(szFile);
	if(hLanguageDll == NULL)
	{
		MessageBoxA(NULL, "No Language DLL found, AudioPlayer will now close", "AudioPlayer Error", MB_OK | MB_ICONERROR);
		ExitProcess(-1);
	}
	tpGetText = (TRANSLATEPROC)GetProcAddress(hLanguageDll, "GetIndexedLocalString");
	return;
}

EXPORT_COMFUNCT char* __cdecl GetCurrentLanguage(void)
{
    char szLangDllPath[MAX_PATH], *szLang = HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, 4);
    char* szLangDllFileName = NULL, *szLangNameStart = NULL;
    GetModuleFileNameA(hLanguageDll, szLangDllPath, MAX_PATH);
    szLangDllFileName = PathFindFileNameA(szLangDllPath);
    szLangNameStart = StrChrA(szLangDllPath, '_') + 1;
    StrCpyNA(szLang, szLangNameStart, 4);
    return szLang;
}

/*void CALLBACK PlayFolderReturn(HWND hwnd, UINT msg, ULONG_PTR ulForegroundWindow, LRESULT msgRetVal)
{
	SetForegroundWindow((HWND)ulForegroundWindow);
	return;
}*/

EXPORT_COMFUNCT LRESULT CALLBACK MultiMediaKeyHook(int iCode, WPARAM wParam, LPARAM lParam)
{
	static HWND hAudioPlayer = NULL;
	PKBDLLHOOKSTRUCT pKeyInfo = (PKBDLLHOOKSTRUCT)lParam;
	DWORD dwVKKey = pKeyInfo->vkCode;
	DWORD dwFlags = pKeyInfo->flags;
	if(hAudioPlayer == NULL)
	{
		hAudioPlayer = FindWindowA("AudioPlayer", "AudioPlayer");
	}
	if((iCode >= 0) && ((dwVKKey >= VK_VOLUME_MUTE) && (dwVKKey <= VK_LAUNCH_MEDIA_SELECT)) && !(dwFlags & LLKHF_UP))
	{
		switch(dwVKKey)
		{
			case VK_VOLUME_MUTE:
			{
				SendMessage(hAudioPlayer, WM_COMMAND, MAKEWPARAM(IDI_VOL_MUTE, 0), 0);
			}
			break;
			case VK_MEDIA_PLAY_PAUSE:
			{
				SendMessage(hAudioPlayer, WM_COMMAND, MAKEWPARAM(IDI_CONT_PAUSE, 0), 0xDEAD);
			}
			break;
			case VK_MEDIA_STOP:
			{
				SendMessage(hAudioPlayer, WM_COMMAND, MAKEWPARAM(IDI_CONT_STOP, 0), 0);
			}
			break;
			case VK_MEDIA_NEXT_TRACK:
			{
				SendMessage(hAudioPlayer, WM_COMMAND, MAKEWPARAM(IDI_PLAYLIST_NEXT, 0), 0);
			}
			break;
			/*case VK_LAUNCH_MEDIA_SELECT: This always seems to open Windows Media Player at the moment 
											so I'm leaving it out until I can figure out what's wrong
			{
				HWND hForeground = GetForegroundWindow();
				SetForegroundWindow(hAudioPlayer);
				SendMessageCallback(hAudioPlayer, WM_COMMAND, MAKEWPARAM(IDI_FILE_PLAY_FOLDER, 0), 0, PlayFolderReturn, (LPARAM)hForeground);
				//SetForegroundWindow(hForeground);
			}
			break;
			*/
		}
	}
	return CallNextHookEx(NULL, iCode, wParam, lParam);
}
